/*
 * @描述: 
 * @创建者: kilomChou
 * @Date: 2021-05-03 16:53:39
 * @最后编辑: kilomChou
 * @LastEditTime: 2021-05-06 08:34:28
 */
import { Node } from "cc";
import { Proto } from "../../common/data/Proto";
import { Util } from "../../common/util/Util";
import { ClientEvent } from "../event/ClientEvent";
import { Conn } from "../net/Conn";
import BaseModel from "./BaseModel";

export default class SnakeModCls extends BaseModel {

    /** 单例 */
    private constructor() { super(); }
    /** 实例 */
    static readonly ins = new SnakeModCls();

    /** 蛇映射 id->modSnake */
    readonly snakeMap = new Map<number, IModSnake>();
    /** 蛇节点字典 id->IModSnakeNode */
    private _snakeNodeDic: { [id: number]: IModSnakeNode } = {};


    listenProto(): void {

        Conn.on(Proto.S2C_SNAKE_UPDATE, data => {
            //蛇更新
            let snakes: IModSnake[] = [];
            let loadSnakes: IModSnake[] = [];
            data.snakes.forEach(snake => {
                let modSnake = this.snakeMap.get(snake.id);
                if (!modSnake) {
                    //蛇加载
                    this.snakeMap.set(snake.id, modSnake = { id: snake.id, snakeNodeMap: new Map() } as IModSnake);
                    loadSnakes.push(modSnake);
                }
                snakes.push(modSnake);
                modSnake.name = snake.name;
                modSnake.w = snake.w;
                modSnake.colors = snake.rgbs.map(rgb => Util.rgb2color(rgb));
                modSnake.loadSnakeNodes = [];

                snake.nodes && snake.nodes.forEach(node => {
                    let modSnakeNode = modSnake.snakeNodeMap.get(node.id);
                    if (!modSnakeNode) {
                        //需要加载的
                        modSnakeNode = this._snakeNodeDic[node.id] = node as IModSnakeNode;
                        modSnake.snakeNodeMap.set(node.id, modSnakeNode);
                        modSnake.loadSnakeNodes.push(modSnakeNode);
                        modSnakeNode.snake = modSnake;
                    } else {
                        //需要更新的
                        modSnakeNode.x = node.x;
                        modSnakeNode.y = node.y;
                    }
                    //角度转换
                    modSnakeNode.ang = node.ang - 90;
                })
            })
            loadSnakes.length && this.sendEvent(ClientEvent.SNAKE_LOAD, loadSnakes);
            this.sendEvent(ClientEvent.SNAKE_NODE_LOAD, snakes);
        })

        Conn.on(Proto.S2C_SNAKE_UNLOAD, data => {
            //蛇卸载
            let snakes: IModSnake[] = [];
            data.snakeIds.forEach(snakeId => {
                let snake = this.snakeMap.get(snakeId);
                if (snake) {
                    snakes.push(snake);
                    this.snakeMap.delete(snakeId);
                }
            })
            this.sendEvent(ClientEvent.SNAKE_UNLOAD, snakes);
        })

        Conn.on(Proto.S2C_SNAKE_NODE_UNLOAD, data => {
            //蛇节点卸载
            let snakeNodes: IModSnakeNode[] = [];
            data.nodeIds.forEach(nodeId => {
                let snakeNode = this._snakeNodeDic[nodeId];
                if (snakeNode) {
                    snakeNodes.push(snakeNode);
                    delete this._snakeNodeDic[nodeId];
                    snakeNode.snake.snakeNodeMap.delete(nodeId);
                }
            })
            this.sendEvent(ClientEvent.SNAKE_NODE_UNLOAD, snakeNodes);
        })
    }

    /** 通过id获取蛇节点 */
    getSnakeNodeById(id: number) {
        return this._snakeNodeDic[id];
    }

}
export const SnakeMod = SnakeModCls.ins;


export interface IModSnake {
    /** 蛇id */
    id: number
    /** 蛇名 */
    name: string
    /** 宽度 */
    w: number
    /** 颜色字符串数组 */
    colors: string[]
    /** 已加载的蛇节点映射 id->IModSnakeNode */
    snakeNodeMap: Map<number, IModSnakeNode>
    /** 需要加载的蛇节点 */
    loadSnakeNodes: IModSnakeNode[]
    /** 场景中的节点 */
    node?: Node
    /** 场景中的名称节点 */
    nameNode?: Node
    /** 场景中的蛇头部节点 */
    headNode?: Node
}

export interface IModSnakeNode {
    /** 蛇 */
    snake: IModSnake
    /** 节点id */
    id: number
    /** 坐标x */
    x: number
    /** 坐标y */
    y: number
    /** 角度 */
    ang: number
    /** 第几节点 */
    idx: number
    /** 场景中的节点 */
    node?: Node
}
